
package com.benimetum.managers;

import com.benimetum.database.Sparql;
import com.benimetum.exceptions.DatabaseConnectException;
import com.benimetum.exceptions.DatabaseWriteOrDeleteException;
import com.benimetum.items.Answer;
import com.benimetum.items.Homework;
import com.benimetum.items.Teacher;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
 *
 * @author Ethem Cem Ozkan
 * @email ethemcem.ozkan@gmail.com
 * No 07110604
 */
public class HomeworkManager
{
    private final static String RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    private final static String ETU="http://www.benimetum.com/benimetum.owl#";
    private final static String FOAF="http://xmlns.com/foaf/0.1/";
    
    public static boolean createHomework(String courseId, File file, String fileInfo, String homeworkText, Date date){
	  Random random=new Random();
	  String id="hw"+random.nextInt(100000000);
	  try {
		Sparql.insertProperty(ETU+id, RDF+"type", ETU+"Homework");
		Sparql.insertProperty(ETU+id, ETU+"isAbout", ETU+courseId);
		Sparql.insertProperty(ETU+courseId, ETU+"hasHomeworks", ETU+id);
		Sparql.insertLiteral(ETU+id, ETU+"id", id);
		Sparql.insertLiteral(ETU+id, ETU+"text", homeworkText);
		Sparql.insertLiteral(ETU+id, ETU+"date", ""+date.getTime());
		FileManager.addFile(file, fileInfo, id);
	  } catch (DatabaseConnectException ex) {
		return false;
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  }
	  return true;
    }
    
    public static boolean deleteHomework(String id){
	  String courseId=getHomeworksCourseId(id);
	  try {
		Sparql.removeLiteral(ETU+id, ETU+"id");
		Sparql.removeLiteral(ETU+id, ETU+"text");
		Sparql.removeLiteral(ETU+id, ETU+"date");
		String[] homeworksFileIds = getHomeworksFileIds(id);
		for (int i = 0; i < homeworksFileIds.length; i++) {
		    String string = homeworksFileIds[i];
		    FileManager.removeFile(string);
		}
		Sparql.removeResource(ETU+id, RDF+"type", ETU+"Homework");
		Sparql.removeResource(ETU+id, ETU+"isAbout", ETU+courseId);
		Sparql.removeResource(ETU+courseId, ETU+"hasHomeworks", ETU+id);
	  } catch (DatabaseConnectException ex) {
		return false;
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  }
	  return true;
    }
    
    public static boolean addAnswer(String homeworkId, File[] file, String[] fileInfo,String studentId){
	  Random random=new Random();
	  String id="ans"+random.nextInt(10000000);
	  try {
		Sparql.insertProperty(ETU+id, RDF+"type", ETU+"Answer");
		Sparql.insertProperty(ETU+id, ETU+"belongsTo", ETU+homeworkId);
		Sparql.insertProperty(ETU+homeworkId, ETU+"hasAnswers", ETU+id);		
		Sparql.insertProperty(ETU+id, ETU+"answeredBy", ETU+studentId);
		Sparql.insertProperty(ETU+studentId, ETU+"hasAnswer", ETU+id);
		Sparql.insertLiteral(ETU+id, ETU+"id", id);
		Sparql.insertLiteral(ETU+id, ETU+"score", "null");
		Sparql.insertProperty(ETU+id, ETU+"checkedBy", "null");
		for (int i = 0; i < fileInfo.length; i++) {
		    FileManager.addFile(file[i], fileInfo[i], id);    
		}
	  } catch (DatabaseConnectException ex) {
		return false;
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  }
	  return true;
    }
    
    public static boolean checkAnswer(String answerId, int score, String teacherId){
	  try {
		Sparql.removeLiteral(ETU+answerId, ETU+"score");
		Sparql.removeResource(ETU+answerId, ETU+"checkedBy", "null");
		Sparql.insertLiteral(ETU+answerId, ETU+"score", score);
		Sparql.insertProperty(ETU+answerId, ETU+"checkedBy", ETU+teacherId);
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  } catch (DatabaseConnectException ex) {
		return false;
	  }
	  return true;
    }
    
    public static String getHomeworksCourseId(String homeworkId){
	  String query="select ?id where{?hw rdf:type etu:Homework. ?hw etu:id \""+homeworkId+"\". ?hw etu:isAbout ?course. ?course etu:id ?id.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  if(!toList.isEmpty())
		return toList.get(0).get("id").toString();
	  return null;
    }
    
    public static String[] getHomeworksFileIds(String homeworkId){
	  String query="select ?id where{?hw rdf:type etu:Homework. ?hw etu:id \""+homeworkId+"\". ?hw etu:hasFiles ?file. ?file etu:uri ?id}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  Iterator<QuerySolution> iterator = toList.iterator();
	  ArrayList<String> files=new ArrayList<String>();
	  while (iterator.hasNext()) {
		QuerySolution querySolution = iterator.next();
		String id = querySolution.get("id").toString().replace("uploads/", "");
		files.add(id);
	  }
	  String[] array=new String[files.size()];
	  return files.toArray(array);
    }
    
    public static Homework[] getStudentsHomework(String studentId){
	  String query="select ?id ?text ?date ?courseId where{?student rdf:type etu:Student. ?student etu:id \""+studentId+"\". ?student etu:hasCourse ?course.?course etu:id ?courseId. ?course etu:hasHomeworks ?hw.?hw etu:id ?id.?hw etu:text ?text."
		    + "?hw etu:date ?date.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  Iterator<QuerySolution> iterator = toList.iterator();
	  ArrayList<Homework> homeworks=new ArrayList<Homework>();
	  while (iterator.hasNext()) {
		QuerySolution querySolution = iterator.next();
		homeworks.add(new Homework(querySolution.get("id").toString(), querySolution.get("text").toString(), new Date(Long.parseLong(querySolution.get("date").toString())), CourseManager.getCourse(querySolution.get("courseId").toString()), FileManager.getHomeworksFiles(querySolution.get("id").toString())));
	  }
	  Homework[] array=new Homework[homeworks.size()];
	  return homeworks.toArray(array);
    }
    
    public static Homework[] getCoursesHomework(String courseId){
	  String query="select ?id ?text ?date ?courseId where{?course rdf:type etu:Course. ?course etu:id \""+courseId+"\". ?course etu:id ?courseId. ?course etu:hasHomeworks ?hw.?hw etu:id ?id.?hw etu:text ?text."
		    + "?hw etu:date ?date.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  Iterator<QuerySolution> iterator = toList.iterator();
	  ArrayList<Homework> homeworks=new ArrayList<Homework>();
	  while (iterator.hasNext()) {
		QuerySolution querySolution = iterator.next();
		homeworks.add(new Homework(querySolution.get("id").toString(), querySolution.get("text").toString(), new Date(Long.parseLong(querySolution.get("date").toString())), CourseManager.getCourse(courseId), FileManager.getHomeworksFiles(querySolution.get("id").toString())));
	  }
	  Homework[] array=new Homework[homeworks.size()];
	  return homeworks.toArray(array);
    }
    
    public static Answer[] getHomeworksAnswer(String homeworkId){
	  String query="select ?id ?score ?teacherId ?studentId where{?hw rdf:type etu:Homework. ?hw etu:id \""+homeworkId+"\". ?hw etu:hasAnswers ?ans. ?ans etu:id ?id. ?ans etu:score ?score."
		    + "?ans etu:answeredBy ?student. ?student etu:id ?studentId.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  Iterator<QuerySolution> iterator = toList.iterator();
	  ArrayList<Answer> answers=new ArrayList<Answer>();
	  int score;
	  while (iterator.hasNext()) {
		QuerySolution querySolution = iterator.next();
		if(querySolution.get("score").toString().equals("null"))
		    score=0;
		else
		    score=Integer.parseInt(querySolution.get("score").toString().substring(0, querySolution.get("score").toString().indexOf("^^")));
		answers.add(new Answer(querySolution.get("id").toString(), score, getAnswersController(querySolution.get("id").toString()), StudentManager.findStudentById(querySolution.get("studentId").toString()), FileManager.getAnswersFiles(querySolution.get("id").toString()), homeworkId));
	  }
	  Answer[] array=new Answer[answers.size()];
	  return answers.toArray(array);
    }
    
    public static Answer[] getStudentsAnswers(String studentId){
	  String query="select ?id ?score ?teacherId ?homeworkId where{?student rdf:type etu:Student. ?student etu:id \""+studentId+"\". ?student etu:hasAnswer ?ans.?ans etu:belongsTo ?hw. ?hw etu:id ?homeworkId. ?ans etu:id ?id. ?ans etu:score ?score."
		    + "?ans etu:answeredBy ?student. ?student etu:id ?studentId.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  Iterator<QuerySolution> iterator = toList.iterator();
	  ArrayList<Answer> answers=new ArrayList<Answer>();
	  int score;
	  while (iterator.hasNext()) {
		QuerySolution querySolution = iterator.next();
		if(querySolution.get("score").toString().equals("null"))
		    score=0;
		else
		    score=Integer.parseInt(querySolution.get("score").toString().substring(0,querySolution.get("score").toString().indexOf("^^")));
		answers.add(new Answer(querySolution.get("id").toString(), score, getAnswersController(querySolution.get("id").toString()), StudentManager.findStudentById(studentId), FileManager.getAnswersFiles(querySolution.get("id").toString()), querySolution.get("homeworkId").toString()));
	  }
	  Answer[] array=new Answer[answers.size()];
	  return answers.toArray(array);
    }
    
    public static Teacher getAnswersController(String answerId){
	  String query="select ?id ?email ?firstName ?surname ?status ?picture where{?ans rdf:type etu:Answer. ?ans etu:id \""+answerId+"\"."
		    + "?ans etu:checkedBy ?teacher. ?teacher etu:email ?email. ?teacher etu:id ?id."
		    + "?teacher foaf:firstName ?firstName. ?teacher foaf:surname ?surname. ?teacher etu:status ?status."
		    + "?teacher etu:profilePicture ?picture.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  if(!toList.isEmpty()){
		Teacher teacher=new Teacher(toList.get(0).get("email").toString(), toList.get(0).get("id").toString(), toList.get(0).get("firstName").toString(), toList.get(0).get("surname").toString(), toList.get(0).get("status").toString(), toList.get(0).get("picture").toString());
		return teacher;
	  }
	  return null;
    }
    
    public static Answer getStudentsAnswer(String studentId, String homeworkId){
	  String query="select ?id ?score ?teacherId ?homeworkId where{?student rdf:type etu:Student. ?student etu:id \""+studentId+"\". ?student etu:hasAnswer ?ans. ?ans etu:belongsTo ?hw. ?hw etu:id \""+homeworkId+"\".?ans etu:belongsTo ?hw. ?hw etu:id ?homeworkId. ?ans etu:id ?id. ?ans etu:score ?score."
		    + "?ans etu:answeredBy ?student. ?student etu:id ?studentId.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  if(!toList.isEmpty()) {
		return new Answer(toList.get(0).get("id").toString(), Integer.parseInt(toList.get(0).get("score").toString()), getAnswersController(toList.get(0).get("id").toString()), StudentManager.findStudentById(studentId), FileManager.getAnswersFiles(toList.get(0).get("id").toString()), toList.get(0).get("homeworkId").toString());
	  }
	  return null;
    }
    
    public static boolean isCreatorOf(String personId, String homeworkId){
	  String query="select ?id ?score ?teacherId ?homeworkId where{?teacher rdf:type etu:Student. ?teacher etu:id \""+personId+"\". ?teacher etu:isTeacherOf ?course. ?course etu:hasHomeworks ?hw. ?hw etu:id \""+homeworkId+"\".?ans etu:belongsTo ?hw. ?hw etu:id ?homeworkId. ?ans etu:id ?id. ?ans etu:score ?score."
		    + "?ans etu:checkedBy ?teacher. ?teacher etu:id ?teacherId. ?ans etu:answeredBy ?student. ?student etu:id ?studentId.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  return !toList.isEmpty();
    }
    
    public static boolean isSent(String personId, String homeworkId){
        String query="select ?hw where{?teacher rdf:type etu:Student. ?teacher etu:id \""+personId+"\". ?teacher etu:hasAnswer ?ans. ?ans etu:belongsTo ?hw. ?hw etu:id \""+homeworkId+"\". ?ans etu:score ?score."
		    + "}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  return !toList.isEmpty();
    }
}
